package com.xmall.product.handler.timer;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmall.define.base.Result;
import com.xmall.define.request.es.EsSpuSearchRequest;
import com.xmall.product.define.constants.ProductConstants;
import com.xmall.product.define.constants.ProductProperties;
import com.xmall.product.entity.SkuInfo;
import com.xmall.product.entity.SpuInfo;
import com.xmall.product.service.ISkuInfoService;
import com.xmall.product.service.ISpuInfoService;
import com.xmall.product.service.other.IMsgService;
import com.xmall.product.service.remote.SearchServiceFeign;
import com.xmall.timer.handler.ITimerTaskHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 商品数据全量同步（新增/更新）
 */
@Slf4j
@Service
public class FullProductUpdateSyncTimerTask implements ITimerTaskHandler {

    @Resource
    private ISpuInfoService spuInfoService;

    @Resource
    private IMsgService msgService;

    @Resource
    private SearchServiceFeign searchServiceFeign;

    @Resource
    private ProductProperties productProperties;

    @Resource
    private ISkuInfoService skuInfoService;

    @Override
    public String key() {
        return ProductConstants.TimerTask.FULL_PRODUCT_UPDATE_SYNC_TASK;
    }

    @Override
    public String name() {
        return "商品数据全量同步";
    }

    @Override
    public String desc() {
        return "商品数据全量同步（新增/更新）";
    }

    @Override
    public String cron() {
        return productProperties.getFullProductUpdateSyncCron();
    }

    @Override
    public void execute() {
        try {
            Date currentTime = new Date();
            Integer page = 1;
            Integer pageSize = productProperties.getFullProductSyncPageSize();

            long count = spuInfoService.count(new QueryWrapper<SpuInfo>().lt("create_time", currentTime));
            int pages = PageUtil.totalPage(count, pageSize);

            while (page <= pages) {
                log.info("FullProductUpdateSyncTimerTask sync: {}, currentPage: {}, pageSize: {}, pages: {}, count: {}", DateUtil.formatDateTime(currentTime), page - 1, pageSize, pages ,count);

                Page<SpuInfo> listPage = spuInfoService.page(new Page<>(page, pageSize), new QueryWrapper<SpuInfo>().lt("create_time", currentTime));
                if (CollectionUtil.isEmpty(listPage.getRecords())) {
                    break;
                }

                listPage.getRecords().forEach(spuInfo -> {
                    try {
                        Long spuId = spuInfo.getId();
                        Integer esVersion = spuInfo.getEsVersion();

                        // 获取数据库中spuId对应的商品数量
                        long skuCount = skuInfoService.count(new QueryWrapper<SkuInfo>().eq("spu_id", spuId));

                        // 获取es中spuId对应的商品数量
                        EsSpuSearchRequest request = new EsSpuSearchRequest();
                        request.setSpuId(spuId);
                        request.setEsVersion(esVersion);
                        Result<Long> skuCountResult = searchServiceFeign.count(request);
                        if(skuCountResult.callSuccess() &&
                                (null == skuCountResult.getData()
                                        || skuCountResult.getData().compareTo(skuCount) != 0)) {
                            msgService.sendProductUpdateMsg(spuId, esVersion);
                            log.info("FullProductUpdateSyncTimerTask spuId: {}, esVersion: {}, need to sync", spuId, esVersion);
                        }
                    }catch (Exception e) {
                        log.error("FullProductUpdateSyncTimerTask error: {}, spuId: {}", e.getMessage(), spuInfo.getId());
                    }
                });

                page ++;
                TimeUnit.SECONDS.sleep(productProperties.getFullProductSyncSleepSeconds());
            }
        }catch (Exception e) {
            log.error("FullProductUpdateSyncTimerTask error: {}", e.getMessage());
        }
    }

}
